﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Netfraction.Common.DataStorage;
using Netfraction.Hub.Scripting;

namespace NetfractionHub.Security
{
	public class PermissionSourceData
	{
		public CodeSource Source { get; set; }

		private static Dictionary<int, CodeSource> codeSourceCache = null;

		public static List<PermissionSourceData> LoadPermissionSourceData()
		{
			SqlDataStore _sqlStore = new SqlDataStore(SecurityDataSource.Source, AccessPermissionBase.PERMISSIONS_DATABASE_NAME);

			AccessPermissionBase.CreateDatabase(_sqlStore);

			if (codeSourceCache == null && (codeSourceCache = CodeSource.LoadCodeSources()) == null)
				return null;
				

			List<PermissionSourceData> psData = new List<PermissionSourceData>();
			PermissionSourceData psd;
			Community.CsharpSqlite.SQLiteClient.SqliteDataReader sdr = _sqlStore.ExecuteQuery("SELECT DisplayName, FullTypeName, CodeSource, PermissionId FROM Permissions");
			if (sdr != null)
			{
				while (sdr.Read())
				{
					if ((psd = LoadPSDFromDataReader(sdr)) != null)
						psData.Add(psd);
				}
			}
			_sqlStore.Disconnect();

			return psData;
		}

		public static PermissionSourceData LoadPermissionSourceDataById(int permissionId)
		{
			SqlDataStore _sqlStore = new SqlDataStore(SecurityDataSource.Source, AccessPermissionBase.PERMISSIONS_DATABASE_NAME);

			AccessPermissionBase.CreateDatabase(_sqlStore);

			PermissionSourceData psd;
			using (Community.CsharpSqlite.SQLiteClient.SqliteDataReader sdr = _sqlStore.ExecuteQuery(String.Format(System.Globalization.CultureInfo.InvariantCulture,
				"SELECT DisplayName, FullTypeName, CodeSource, PermissionId FROM Permissions WHERE PermissionId={0} LIMIT 1",
				permissionId)))
			{
				if (sdr != null)
				{
					while (sdr.Read())
					{
						if ((psd = LoadPSDFromDataReader(sdr)) != null)
							return psd;
					}
				}
				//_sqlStore.Disconnect();
			}
			return null;
		}

		[SqlVulnerabilityAttribute("Potential SQL Injection flaw.")]
		public static PermissionSourceData LoadPermissionSourceDataByName(string fullName)
		{
			SqlDataStore _sqlStore = new SqlDataStore(SecurityDataSource.Source, AccessPermissionBase.PERMISSIONS_DATABASE_NAME);

			AccessPermissionBase.CreateDatabase(_sqlStore);

			PermissionSourceData psd;
			using (Community.CsharpSqlite.SQLiteClient.SqliteDataReader sdr = _sqlStore.ExecuteQuery(String.Format(System.Globalization.CultureInfo.InvariantCulture,
				"SELECT DisplayName, FullTypeName, CodeSource, PermissionId FROM Permissions WHERE FullTypeName='{0}' LIMIT 1",
				fullName)))
			{
				if (sdr != null)
				{
					while (sdr.Read())
					{
						if ((psd = LoadPSDFromDataReader(sdr)) != null)
							return psd;
					}
				}
				//_sqlStore.Disconnect();
			}
			return null;
		}

		private static PermissionSourceData LoadPSDFromDataReader(Community.CsharpSqlite.SQLiteClient.SqliteDataReader sdr)
		{
			PermissionSourceData psd = new PermissionSourceData();
			try
			{
				psd.DisplayName = sdr.GetString(0);
				psd.FullName = sdr.GetString(1);
				int codeSourceId = sdr.GetInt32(2);
				psd.Source = codeSourceCache.ContainsKey(codeSourceId) ? codeSourceCache[codeSourceId] : null;
				psd.PermissionId = sdr.GetInt32(3);
				if (psd.Source != null)
					return psd;
			}
			catch (InvalidCastException ice)
			{
				Console.WriteLine(ice.Message);
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
			return psd;
		}

		public int PermissionId { get; set; }

		public string DisplayName { get; set; }

		public string FullName { get; set; }
	}
}
